home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / aztecnos.arc / MAIN.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-13  |  12.7 KB  |  660 lines

  1. /* Main network program - provides both client and server functions */
  2. #define HOSTNAMELEN 32        /* changed from 16 by Bdale 860812 */
  3. #include <stdio.h>
  4. #include <time.h>
  5. #include "config.h"
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "socket.h"
  9. #include "iface.h"
  10. #include "ftpcli.h"
  11. #include "telnet.h"
  12. #include "ax25tnc.h"
  13. #include "remote.h"
  14. #include "session.h"
  15. #include "cmdparse.h"
  16. #include "ax25.h"
  17. #include "enet.h"
  18. #include "timer.h"
  19. #include "proc.h"
  20. #include "tty.h"
  21. #include "daemon.h"
  22.  
  23. #ifdef    ASY
  24. #include "asy.h"
  25. #include "slip.h"
  26. #endif
  27.  
  28. #ifdef    NRS
  29. #include "nrs.h"
  30. #endif
  31.  
  32. #ifdef UNIX        /* BSD or SYS5 */
  33. #include "unix.h"
  34. #endif
  35.  
  36. #ifdef AMIGA
  37. #include "amiga.h"
  38. #endif
  39.  
  40. #ifdef MAC
  41. #include "mac.h"
  42. #endif
  43.  
  44. #ifdef MSDOS
  45. #include "asy.h"
  46. #endif
  47.  
  48. #ifdef    TRACE
  49. #include "trace.h"
  50. /* Dummy structure for loopback tracing */
  51. struct iface Loopback = { NULLIF, "loopback" };
  52. #endif
  53.  
  54. extern struct cmds Cmds[],Startcmds[],Stopcmds[];
  55. extern struct daemon Daemons[];
  56. extern struct iface *Ifaces;
  57. extern char Version[];
  58. extern char Startup[];    /* File to read startup commands from */
  59. extern int Refuse_echo;
  60. extern int Unix_line_mode;
  61. extern struct cmds Attab[];
  62. extern struct iface *Ifaces;
  63. char *fgets(),*strncpy();
  64. struct mbuf *ttydriv();
  65. int cmdparse();
  66. void showtrace();
  67.  
  68. FILE *Logfp;
  69. char Badhost[] = "Unknown host %s\n";
  70. char Hostname[HOSTNAMELEN];    
  71. unsigned Nsessions = NSESSIONS;
  72. int16 Lport = 1001;
  73. char Prompt[] = "net> ";
  74. char Nospace[] = "No space!!\n";    /* Generic malloc fail message */
  75. struct mbuf *Hopper;
  76.  
  77. #ifndef    MSDOS            /* PC uses F-10 key always */
  78. static char Escape = 0x1d;    /* default escape character is ^] */
  79. #endif
  80.  
  81. struct mbuf *Cmdq;
  82. struct proc *Cmdpp;
  83.  
  84. main(argc,argv)
  85. int argc;
  86. char *argv[];
  87. {
  88.     char *inbuf;
  89.     FILE *fp;
  90.     struct daemon *tp;
  91.     struct mbuf *bp;
  92.  
  93.     kinit();
  94.     ioinit();
  95.     sockinit(40);
  96.     Cmdpp = mainproc("cmdintrp");
  97.     ttysetmode(TTY_ECHO|TTY_EDIT);
  98.     printf("KA9Q Internet Protocol Package, v%s\n",Version);
  99.     printf("Copyright 1989 by Phil Karn, KA9Q\n");
  100.     fflush(stdout);
  101.     Sessions = (struct session *)calloc(Nsessions,sizeof(struct session));
  102.  
  103.     /* Start background Daemons */
  104.     for(tp=Daemons;;tp++){
  105.         if(tp->name == NULLCHAR)
  106.             break;
  107.         newproc(tp->name,tp->stksize,tp->fp,0,NULLCHAR);
  108.     }
  109.  
  110.     if(argc > 1){
  111.         /* Read startup file named on command line */
  112.         fp = fopen(argv[1],"r");
  113.     } else {
  114.         fp = fopen(Startup,"r");
  115.     }
  116.     if(fp != NULLFILE){
  117.         inbuf = malloc(BUFSIZ);
  118.         while(fgets(inbuf,BUFSIZ,fp) != NULLCHAR){
  119.             cmdparse(Cmds,inbuf);
  120.         }
  121.         fclose(fp);
  122.         free(inbuf);
  123.     }        
  124.  
  125.     /* Now loop forever, processing commands */
  126.     for(;;){
  127.         printf(Prompt);
  128.         while(Cmdq == NULLBUF)
  129.             pwait(&Cmdq);
  130.         bp = dequeue(&Cmdq);
  131.         (void)cmdparse(Cmds,bp->data);
  132.         free_p(bp);
  133.         ttysetmode(TTY_ECHO|TTY_EDIT);
  134.     }
  135. }
  136. /* Keyboard input process */
  137. void
  138. keyboard()
  139. {
  140.     int c;
  141.     struct mbuf *bp;
  142.  
  143.     /* Keyboard process loop */
  144.     for(;;){
  145.         c = kbread();
  146. #ifndef    MSDOS
  147.         if(c == Escape && Escape != 0)
  148.             c = -2;
  149. #endif
  150.         /* c == -2 means the command escape key */
  151.         if(c == -2){
  152.             /* Save current tty mode and set cooked */
  153.             if(Current != NULLSESSION){
  154.                 Current->ttymode = ttygetmode();
  155.                 Lastcurrent = Current;
  156.                 Current = NULLSESSION;
  157.                 ttysetmode(TTY_ECHO|TTY_EDIT);
  158.                 printf("\n");
  159.                 /* Wake up the command interpreter */
  160.                 alert(Cmdpp,0);
  161.             }
  162.         /* Else give to line editor; if done, queue it */
  163.         } else if((bp = ttydriv(c)) != NULLBUF){
  164.             if(Current != NULLSESSION)
  165.                 enqueue(&Current->input,bp);
  166.             else 
  167.                 enqueue(&Cmdq,bp);
  168.         }
  169.     }
  170. }
  171. /* Process packets in the Hopper */
  172. void
  173. network()
  174. {
  175.     struct mbuf *bp;
  176.     struct phdr phdr;
  177.     char i_state;
  178.  
  179. loop:    i_state = dirps();
  180.     while(Hopper == NULLBUF)
  181.         pwait(&Hopper);
  182.     restore(i_state);
  183.  
  184.     /* Process the input packet */
  185.     bp = dequeue(&Hopper);
  186.     pullup(&bp,(char *)&phdr,sizeof(phdr));
  187.     dump(phdr.iface,IF_TRACE_IN,phdr.type,bp);
  188.     switch(phdr.type){
  189. #ifdef    AX25
  190.     case TYPE_KISS:
  191.         /* Toss the type field and handle as AX.25 */
  192.         pullup(&bp,NULLCHAR,1);    /*note fall-thru */
  193.     case TYPE_AX25:
  194.         ax_recv(phdr.iface,bp);
  195.         break;
  196. #endif
  197.     case TYPE_ETHER:
  198.         eproc(phdr.iface,bp);
  199.         break;
  200.     case TYPE_IP:
  201.         ip_route(bp,0);
  202.         break;
  203.     case TYPE_APPLETALK:
  204.     default:
  205.         free_p(bp);
  206.         break;
  207.     }
  208.     goto loop;
  209. }
  210. /* Standard commands called from main */
  211. int
  212. doexit(argc,argv)
  213. int argc;
  214. char *argv[];
  215. {
  216.     if(Logfp != NULLFILE)
  217.         fclose(Logfp);
  218.     iostop();
  219.     exit(0);
  220. }
  221. int
  222. dohostname(argc,argv)
  223. int argc;
  224. char *argv[];
  225. {
  226.     if(argc < 2)
  227.         printf("%s\n",Hostname);
  228.     else 
  229.         strncpy(Hostname,argv[1],HOSTNAMELEN);
  230.     return 0;
  231. }
  232. int
  233. dolog(argc,argv)
  234. int argc;
  235. char *argv[];
  236. {
  237.     static char logname[15];
  238.  
  239.     if(argc < 2){
  240.         if(Logfp)
  241.             printf("Logging to %s\n",logname);
  242.         else
  243.             printf("Logging off\n");
  244.         return 0;
  245.     }
  246.     if(Logfp){
  247.         fclose(Logfp);
  248.         Logfp = NULLFILE;
  249.     }
  250.     if(strcmp(argv[1],"stop") != 0){
  251.         strncpy(logname,argv[1],15);
  252.         Logfp = fopen(logname,"a+");
  253.     }
  254.     return 0;
  255. }
  256. int
  257. dohelp(argc,argv)
  258. int argc;
  259. char *argv[];
  260. {
  261.     register struct cmds *cmdp;
  262.     int i,j;
  263.  
  264.     printf("Main commands:\n");
  265.     for(i=0,cmdp = Cmds;cmdp->name != NULL;cmdp++,i++){
  266.         printf("%s",cmdp->name);
  267.         if((i % 4) == 3)
  268.             printf("\n");
  269.         else {
  270.             for(j=strlen(cmdp->name);j < 16; j++)
  271.                 putchar(' ');
  272.         }
  273.     }
  274.     if((i % 4) != 0)
  275.         printf("\n");
  276.     return 0;
  277. }
  278. int
  279. doecho(argc,argv)
  280. int argc;
  281. char *argv[];
  282. {
  283.     if(argc < 2){
  284.         if(Refuse_echo)
  285.             printf("Refuse\n");
  286.         else
  287.             printf("Accept\n");
  288.     } else {
  289.         if(argv[1][0] == 'r')
  290.             Refuse_echo = 1;
  291.         else if(argv[1][0] == 'a')
  292.             Refuse_echo = 0;
  293.         else
  294.             return -1;
  295.     }
  296.     return 0;
  297. }
  298. /* set for unix end of line for remote echo mode telnet */
  299. int
  300. doeol(argc,argv)
  301. int argc;
  302. char *argv[];
  303. {
  304.     if(argc < 2){
  305.         if(Unix_line_mode)
  306.             printf("Unix\n");
  307.         else
  308.             printf("Standard\n");
  309.     } else {
  310.         if(strcmp(argv[1],"unix") == 0)
  311.             Unix_line_mode = 1;
  312.         else if(strcmp(argv[1],"standard") == 0)
  313.             Unix_line_mode = 0;
  314.         else {
  315.             return -1;
  316.         }
  317.     }
  318.     return 0;
  319. }
  320. /* Attach an interface
  321.  * Syntax: attach <hw type> <I/O address> <vector> <mode> <label> <bufsize> [<speed>]
  322.  */
  323. int
  324. doattach(argc,argv)
  325. int argc;
  326. char *argv[];
  327. {
  328.     return subcmd(Attab,argc,argv);
  329. }
  330. /* Manipulate I/O device parameters */
  331. int
  332. doparam(argc,argv)
  333. int argc;
  334. char *argv[];
  335. {
  336.     register struct iface *ifp;
  337.  
  338.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  339.         if(strcmp(argv[1],ifp->name) == 0)
  340.             break;
  341.     }
  342.     if(ifp == NULLIF){
  343.         printf("Interface \"%s\" unknown\n",argv[1]);
  344.         return 1;
  345.     }
  346.     if(ifp->ioctl == NULLFP){
  347.         printf("Not supported\n");
  348.         return 1;
  349.     }
  350.     /* Pass rest of args to device-specific code */
  351.     return (*ifp->ioctl)(ifp,argc-2,argv+2);
  352. }
  353. /* Log messages of the form
  354.  * Tue Jan 31 00:00:00 1987 44.64.0.7:1003 open FTP
  355.  */
  356. /*VARARGS2*/
  357. log(s,fmt,arg1,arg2,arg3,arg4)
  358. int s;
  359. char *fmt;
  360. int arg1,arg2,arg3,arg4;
  361. {
  362.     char *cp;
  363.     long t;
  364.     int fd,i;
  365.     struct sockaddr fsocket;
  366.  
  367.     if(Logfp == NULLFILE)
  368.         return;
  369.     time(&t);
  370.     cp = ctime(&t);
  371.     rip(cp);
  372.     i = SOCKSIZE;
  373.     fprintf(Logfp,"%s",cp);
  374.     if(getpeername(s,(char *)&fsocket,&i) != -1)
  375.         fprintf(Logfp," %s",psocket(&fsocket));
  376.  
  377.     fprintf(Logfp," - ");
  378.     fprintf(Logfp,fmt,arg1,arg2,arg3,arg4);
  379.     fprintf(Logfp,"\n");
  380.     fflush(Logfp);
  381. #ifdef    MSDOS
  382.     /* MS-DOS doesn't really flush files until they're closed */
  383.     fd = fileno(Logfp);
  384.     if((fd = dup(fd)) != -1)
  385.         close(fd);
  386. #endif
  387. }
  388. /* Configuration-dependent code */
  389.  
  390. /* List of supported hardware devices */
  391. int ec_attach(),asy_attach(),pc_attach(),eg_attach(),hapn_attach(),at_attach(),
  392.     nr_attach(),pk_attach(),hs_attach();
  393.  
  394. struct cmds Attab[] = {
  395. #ifdef    PC_EC
  396.     /* 3-Com Ethernet interface */
  397.     "3c500", ec_attach, 0, 7, 
  398.     "attach 3c500 <address> <vector> arpa <label> <buffers> <mtu>",
  399. #endif
  400. #ifdef    ASY
  401.     /* Ordinary PC asynchronous adaptor */
  402.     "asy", asy_attach, 0, 8, 
  403.     "attach asy <address> <vector> slip|ax25|nrs <label> <buffers> <mtu> <speed>",
  404. #endif
  405. #ifdef    PC100
  406.     /* PACCOMM PC-100 8530 HDLC adaptor */
  407.     "pc100", pc_attach, 0, 8, 
  408.     "attach pc100 <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  409. #endif
  410. #ifdef    EAGLE
  411.     /* EAGLE RS-232C 8530 HDLC adaptor */
  412.     "eagle", eg_attach, 0, 8,
  413.     "attach eagle <address> <vector> ax25 <label> <buffers> <mtu> <speed>",
  414. #endif
  415. #ifdef    HAPN
  416.     /* Hamilton Area Packet Radio (HAPN) 8273 HDLC adaptor */
  417.     "hapn", hapn_attach, 0, 8,
  418.     "attach hapn <address> <vector> ax25 <label> <rx bufsize> <mtu> csma|full",
  419. #endif
  420. #ifdef    APPLETALK
  421.     /* Macintosh AppleTalk */
  422.     "0", at_attach, 0, 7,
  423.     "attach 0 <protocol type> <device> arpa <label> <rx bufsize> <mtu>",
  424. #endif
  425. #ifdef NETROM
  426.     /* fake netrom interface */
  427.     "netrom", nr_attach, 0, 1,
  428.     "attach netrom",
  429. #endif
  430. #ifdef    PACKET
  431.     /* FTP Software's packet driver spec */
  432.     "packet", pk_attach, 0, 4,
  433.     "attach packet <int#> <label> <buffers> <mtu>",
  434. #endif
  435. #ifdef    HS
  436.     /* Special high speed driver for DRSI PCPA or Eagle cards */
  437.     "hs", hs_attach, 0, 7,
  438.     "attach hs <address> <vector> ax25 <label> <buffers> <mtu> <txdelay> <persistence>",
  439. #endif
  440.     NULLCHAR, NULLFP, 0, 0,
  441.     "Unknown device",
  442. };
  443.  
  444. /* Protocol tracing function pointers */
  445. #ifdef    TRACE
  446. int ax25_dump(),ether_dump(),ip_dump(),at_dump(),ki_dump();
  447.  
  448. int (*Tracef[])() = {
  449. #ifdef    AX25
  450.     ax25_dump,
  451. #else
  452.     NULLFP,
  453. #endif
  454.  
  455. #ifdef    ETHER
  456.     ether_dump,
  457. #else
  458.     NULLFP,
  459. #endif
  460.     ip_dump,
  461.  
  462. #ifdef    APPLETALK
  463.     at_dump,
  464. #else
  465.     NULLFP,
  466. #endif
  467.  
  468. #ifdef    KISS
  469.     ki_dump,
  470. #else
  471.     NULLFP,
  472. #endif
  473. };
  474. #else    /* TRACE */
  475. int (*Tracef[])() = { NULLFP };    /* No tracing at all */
  476. dump(iface,direction,type,bp)
  477. struct iface *iface;
  478. int direction;
  479. unsigned type;
  480. struct mbuf *bp;
  481. {
  482. }
  483. #endif    /* TRACE */
  484.  
  485. #ifndef    NETROM
  486. #ifdef    AX25
  487. struct ax25_addr Nr_nodebc;
  488. #endif    /* AX25 */
  489. nr_route(bp)
  490. struct mbuf *bp;
  491. {
  492.     free_p(bp);
  493. }
  494. nr_nodercv(bp)
  495. struct mbuf *bp;
  496. {
  497.     free_p(bp);
  498. }
  499. #endif    /* NETROM */
  500.  
  501. /* Display or set IP interface control flags */
  502. domode(argc,argv)
  503. int argc;
  504. char *argv[];
  505. {
  506.     register struct iface *ifp;
  507.  
  508.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  509.         if(strcmp(argv[1],ifp->name) == 0)
  510.             break;
  511.     }
  512.     if(ifp == NULLIF){
  513.         printf("Interface \"%s\" unknown\n",argv[1]);
  514.         return 1;
  515.     }
  516.     if(argc < 3){
  517.         printf("%s: %s\n",ifp->name,
  518.          (ifp->flags & CONNECT_MODE) ? "VC mode" : "Datagram mode");
  519.         return 0;
  520.     }
  521.     switch(argv[2][0]){
  522.     case 'v':
  523.     case 'c':
  524.     case 'V':
  525.     case 'C':
  526.         ifp->flags = CONNECT_MODE;
  527.         break;
  528.     case 'd':
  529.     case 'D':
  530.         ifp->flags = DATAGRAM_MODE;
  531.         break;
  532.     default:
  533.         printf("Usage: %s [vc | datagram]\n",argv[0]);
  534.         return 1;
  535.     }
  536.     return 0;
  537. }
  538.  
  539. #ifdef SERVERS
  540. dostart(argc,argv)
  541. int argc;
  542. char *argv[];
  543. {
  544.     return subcmd(Startcmds,argc,argv);
  545. }
  546. dostop(argc,argv)
  547. int argc;
  548. char *argv[];
  549. {
  550.     return subcmd(Stopcmds,argc,argv);
  551. }
  552. #endif SERVERS
  553.  
  554. #ifdef    TRACE
  555. int
  556. dotrace(argc,argv)
  557. int argc;
  558. char *argv[];
  559. {
  560.     struct iface *ifp;
  561.  
  562.     if(argc < 2){
  563.         showtrace(&Loopback);
  564.         for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  565.             showtrace(ifp);
  566.         return 0;
  567.     }
  568.     if(strcmp("loopback",argv[1]) == 0)
  569.         ifp = &Loopback;
  570.     else 
  571.         for(ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
  572.             if(strcmp(ifp->name,argv[1]) == 0)
  573.                 break;
  574.  
  575.     if(ifp == NULLIF){
  576.         printf("Interface %s unknown\n",argv[1]);
  577.         return 1;
  578.     }
  579.     if(argc >= 3)
  580.         ifp->trace = htoi(argv[2]);
  581.  
  582.     showtrace(ifp);
  583.     return 0;
  584. }
  585. /* Display the trace flags for a particular interface */
  586. void
  587. showtrace(ifp)
  588. register struct iface *ifp;
  589. {
  590.     if(ifp == NULLIF)
  591.         return;
  592.     printf("%s:",ifp->name);
  593.     if(ifp->trace & (IF_TRACE_IN | IF_TRACE_OUT)){
  594.         if(ifp->trace & IF_TRACE_IN)
  595.             printf(" input");
  596.         if(ifp->trace & IF_TRACE_OUT)
  597.             printf(" output");
  598.  
  599.         if(ifp->trace & IF_TRACE_HEX)
  600.             printf(" (Hex/ASCII dump)");
  601.         else if(ifp->trace & IF_TRACE_ASCII)
  602.             printf(" (ASCII dump)");
  603.         else
  604.             printf(" (headers only)");
  605.         printf("\n");
  606.     } else
  607.         printf(" tracing off\n");
  608. }
  609. #endif    /* TRACE */
  610.  
  611. #ifndef    MSDOS
  612. static
  613. int
  614. doescape(argc,argv)
  615. int argc;
  616. char *argv[];
  617. {
  618.     if(argc < 2)
  619.         printf("0x%x\n",Escape);
  620.     else 
  621.         Escape = *argv[1];
  622.     return 0;
  623. }
  624. #endif    MSDOS
  625. int
  626. doremote(argc,argv)
  627. int argc;
  628. char *argv[];
  629. {
  630.     struct sockaddr_in fsock;
  631.     int s;
  632.     char data;
  633.     extern int errno;
  634.  
  635.     fsock.sin_family = AF_INET;
  636.     fsock.sin_addr.s_addr = resolve(argv[1]);
  637.     fsock.sin_port = atoi(argv[2]);
  638.  
  639.     if(strcmp(argv[3],"reset") == 0){
  640.         data = SYS_RESET;
  641.     } else if(strcmp(argv[3],"exit") == 0){
  642.         data = SYS_EXIT;
  643.     } else {
  644.         printf("Unknown command %s\n",argv[3]);
  645.         return 1;
  646.     }
  647.     if((s = socket(AF_INET,SOCK_DGRAM,0)) == -1){
  648.         printf("socket failed\n");
  649.         return 1;
  650.     }
  651.     if(sendto(s,&data,1,0,(char *)&fsock,sizeof(fsock)) == -1){
  652.         printf("sendto failed, errno %d\n",errno);
  653.         close_s(s);
  654.         return 1;
  655.     }
  656.     close_s(s);
  657.     return 0;
  658. }
  659.  
  660.